<?php
class Pageley_Gateway_Database_MySql_Statement implements Pageley_Gateway_Database_Statement {

    private $sql;
    private $connection;
    private static $BAD_SQL_CODES = array(1051, 1052, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066);
    private static $CONSTRAINT_VIOLATION_CODES = array(1022, 1048);
    private static $PERMISSION_DENIED_CODES = array(1044, 1045);

    public function __construct($sql, $connection) {
        $this->sql = $sql;
        $this->connection = $connection;
    }

    public function execute($values) {
        $sql = $this->sql;
        if(Pageley_Log::isDebugEnabled($this)) {
            Pageley_Log::debug($this, "Prepared query: [" . $sql . "], values: " . $values);
        }
		if($values != null) {
			foreach($values as $key => $value) {
				if(is_numeric($key)) {
					$sql = $this->setParameterByRegex("/\?/", $value, $sql, 1);
				} else {
					$sql = $this->setParameterByRegex("/:" . $key . "([^\w_])|:" . $key . "$/", $value, $sql, -1);
				}
			}
		}
        if(Pageley_Log::isDebugEnabled($this)) {
            Pageley_Log::debug($this, "Connection " . $this->connection->getId() . " - Executing SQL: [" . $sql . "]");
        }
		$result = @mysql_query($sql, $this->connection->getResource());
		if(!$result) {
			$this->throwException($sql);
		}
		return new Pageley_Gateway_Database_MySql_ResultSet($result, $this->connection);
	}

	private function setParameterByRegex($regex, $value, $sql, $limit) {
		$replacement = null;
		if($value === null) {
			$replacement = "NULL";
		} else {
			$replacement = "'" . mysql_real_escape_string($value, $this->connection->getResource()) . "'";
		}
		return preg_replace($regex, $replacement . "$1", $sql, $limit);
	}

	private function throwException() {
		if(in_array(mysql_errno($this->connection->getResource()), self::$BAD_SQL_CODES)) {
			throw new Pageley_Gateway_Database_BadSqlException("Bad syntax in statement [" . $this->sql . "].\n Error "
				. mysql_errno($this->connection->getResource()) . ": " . mysql_error($this->connection->getResource()));
		} else if(in_array(mysql_errno($this->connection->getResource()), self::$CONSTRAINT_VIOLATION_CODES)) {
			throw new Pageley_Gateway_Database_ConstraintViolationException("Constraint violation when executing statement [" . $this->sql . "].\n Error "
				. mysql_errno($this->connection->getResource()) . ": " . mysql_error($this->connection->getResource()));
		} else if(in_array(mysql_errno($this->connection->getResource()), self::$PERMISSION_DENIED_CODES)) {
			throw new Pageley_Gateway_Database_PermissionDeniedException("Permission denied on executing statement [" . $this->sql . "].\n Error "
				. mysql_errno($this->connection->getResource()) . ": " . mysql_error($this->connection->getResource()));
		} else {
			throw new Pageley_Gateway_Database_Exception("Failed to execute statement [" . $this->sql . "].\n Error "
				. mysql_errno($this->connection->getResource()) . ": " . mysql_error($this->connection->getResource()));
		}
	}
}